第 9 章:Ansible 最佳實踐
官方建議的目錄結構
官方建議的目錄結構
production # inventory file for production.
staging # inventory file for staging.
group_vars/
group1 # here we assign variables to particular groups
group2
host_vars/
hostname1 # if systems need specific variables, put them here
hostname2
site.yml # master playbook
webservers.yml # playbook for webserver tier
dbservers.yml # playbook for dbserver tier
roles/
common/ # role name
tasks/ #
main.yml # main tasks file.
handlers/ #
main.yml # handlers file.
templates/ #
ntp.conf.j2 # templates end in .j2.
files/ #
bar.txt # files
foo.sh # script files
vars/ #
main.yml # variables with this role.
defaults/ #
main.yml # default variables.
meta/ #
main.yml # role dependencies
production
,staging
:藉由 inventory file 來切換環境webservers.yml
:網頁伺服器一層的 playbook。dbservers.yml
:資料庫伺服器一層的 playbook。django
django 專案目錄結構範例
django 專案目錄結構範例
README.md # 該專案的說明文件。
Vagrantfile
ansible.cfg # configure for ansible
files/
id_rsa_deploy # 用 Git 部署的 ssh key。
ssl_key/
...
group_vars/
all # 各環境共用的群組變數。
local # 本機開發的群組變數。
production # 正式環境的群組變數。
staging # 測試環境的群組變數。
production # 正式環境的 inventory file。
requirements.yml
restart_service.yml # 重開 API 服務的 playbook。
roles/
chusiang.switch-apt-mirror/
...
setup.yml # 主要 playbook。
staging # 測試環境的 inventory file。
tasks/
restart_api.yml # 重開 api 的 tasks。
setting_api.yml # 設定 api 的 tasks。
setting_nginx.yml # 設定 nginx 的 tasks。
setup.yml # 主要安裝流程的 tasks。
templates/
local_settings.py.j2
nginx.conf.j2 # nginx vhost.
nginx_ssl.conf # nginx vhost (ssl).
supervisor.conf.j2
tests/
Dockerfile # 用 Docker 跑測試。
update_config.yml
Vagrantfile
:在本機主要使用 Vagrant 搭配group_vars/local
進行開發。ansible.cfg
:依各專案客製 Ansible 相關環境。files/
:集中管理要使用 files module 複製到 Managed node 的檔案。group_vars/
:設定 staging、production 等不同群組 (環境) 變數 ;若有共用變數的部份可寫在all
檔案裡。setup.yml
:include 各種 tasks 的主要 playbook。tasks/
:將各種不同任務獨立出來的 tasks,在裡分別為restart_api.yml
,setting_nginx.yml
和setup.yml
。templates/
:集中管理要使用 templates module 複製到 Managed node 的檔案。
Jenkins 專案目錄結構範例
Jenkins 專案目錄結構範例
my-ansible/
├── LICENSE
├── README.md
├── Vagrantfile
├── ansible.cfg
|
├── inventory
|
├── docker-jenkins.yml
├── jenkins-ansible-lint.yml
├── playbook_example.yml
|
└── roles/
├── docker/
├── docker-jenkins/
│ ├── defaults/
│ │ └── main.yml
│ ├── files/
│ │ └── plugins.txt
│ ├── meta/
│ │ └── main.yml
│ ├── tasks/
│ │ ├── dependencies.yml
│ │ ├── main.yml
│ │ └── setup.yml
│ └── templates/
│ ├── Dockerfile.j2
│ └── security.groovy.j2
├── jenkins-ansible-lint/
└── pip/
- 根目錄舉凡
LICENSE
,README.md
,Vagrantfile
以及ansible.cfg
這類的說明、設定檔案,我都習慣將它們直接放在根目錄下。另外,由於在這個專案內我只有一個 inventory file,所以我也直接將其擺放在根目錄下,如果有多個 inventory files,還可以加入group_vars/
以及host_vars/
來定義不同環境下會用到的變數。除此之外,這個 Ansbile 專案內,我還放了三份不同的 playbook roles/
在這裡我存放了所有跟這個專案有關的 roles。由於每個 role 的結構類似,所以我以其中的docker-jenkins
這個 role 來做簡單介紹:defaults/
在這個資料夾下,通常被用來定義優先度較低的變數。除了defaults/
,習慣上我還會另外將只跟這個 role 有關的變數放在vars/
的資料夾下來做使用目的上的區分。關於 Ansbile 變數的優先權,可以參考官方在這裡的說明文件files/
這個資料夾內通常存放著這個 role 在部署過程中會需要使用或執行的檔案templates/
由於 Ansible 是用 Python 開發的一個自動化工具,所以也原生支援 Jinja2 這套模版引擎 (templating engine)。與files/
下的檔案不同,這個資料夾下的檔案通常都以.j2
作為副檔名。Ansible 會根據執行環境、傳遞參數等等的不同在部署過程中來對 template file 做某種程度上調整。tasks/
整個 role 中最核心的部分。這裡面定義了這個 role 的部署邏輯以及運行任務。在這個資料夾下可以不只有一個檔案,然後在main.yml
裡定義何時呼叫其他檔案meta/meta/
資料夾內定義了這個 role 的依賴 (dependencies) 關係。以這個docker-jenkins
為例,docker
這個 role 就是其依賴。在運行時,會在運行完meta/
內定義的所有 dependencies 後才接著執行 role 本身的任務。我們可以充分利用這個特色來重複組合及利用已經定義好的 role 以減少重造輪子的情況發生handlers/
我們會將所有 handlers 事件存放在這個目錄下。雖然這個專案並沒有使用到任何 handler,但 handler 是 Ansible 中非常好用的一個功能。我們可以根據 Ansible 運行時 tasks 狀態的改變來通知 (notify) handlers。最重要的特色是,無論有多少個 task notify 同一個 handler,該 handler 都只會運行一次。非常常見 handler 的實踐之一就是在檔案被修改後重啟 services
撰寫原則
- 透過
inventory
和group_vars
來定義 local, staging 和 production 等各環境的主機和變數。 - 儘可能的把重複的 tasks 獨立出來,然後讓 playbook 依不同需求 include 進來用。在這個例子裡,凍仁把
setup.yml
和update_config.yml
兩個 playbook 中重複的 tasks 獨立成tasks/setting_api.yml
,並透過include
重複使用。